#pragma once
#include "Inet_data.h"
using namespace std;

class Tcp
{
public:
    Tcp(uint16_t port)
        : _port(port)
    {
    }

    void Creat_socket()
    {
        // 1.创建套接字(创建文件细节)
        _sockfd = socket(AF_INET, SOCK_STREAM, 0); // 创建套接字(域、套接字类型、协议)参数2基本可以固定tcp/udp
        if (_sockfd < 0)
        {
            cerr << "创建套接字失败" << endl;
            exit(-1);
        }
    }

    void Bind()
    {
        // 2.绑定(网络信息与文件信息相关联)
        struct sockaddr_in local;           //
        local.sin_family = AF_INET;         // 域，用于sockaddr类型接收时的辨别字段
        local.sin_port = htons(_port);      // 端口号 主机转网络(用于发送)
        local.sin_addr.s_addr = INADDR_ANY; // 地址任意

        int n = bind(_sockfd, (sockaddr *)&local, sizeof(local));
        if (n != 0)
        {
            cerr << "套接字绑定失败!!!" << endl;
        }
    }

    void Listen() // 监听，等待客户端进行connect
    {
        if (listen(_sockfd, 5) == -1) // 参数二是全连接队列
        {
            cerr << "listen fails!!!" << endl;
            exit(-1);
        }
    }

    uint16_t Accept() // 返回一个连接套接字，用于网络数据通信
    {
        while (true)
        {
            struct sockaddr_in local;
            socklen_t len;
            uint16_t _connect_sockfd = accept(_sockfd, (sockaddr *)&local, &len);
            if (_connect_sockfd < 0)
            {
                cout << "accept error ,continue..." << endl;
                continue;
            }
            cout << "成功接收客户端连接..." << endl;
            Inet_data tmp(_connect_sockfd, local);
            tmp.Inet_info();

            return _connect_sockfd;
        }
    }

    bool Recv(int fd, string &buffer, int sz)
    {
        char tmp[sz];
        int n = recv(fd, tmp, sz, 0);
        if (n > 0)
        {
            tmp[n] = 0;
            buffer += tmp;
            if (buffer == "quit\r\n")
            {
                cout << "已断开与客户端的连接..." << endl;
                return false;
            }
            return true;
        }
        else
            return false;
    }

    uint16_t Get_sockfd()
    {
        return _sockfd;
    }

    ~Tcp()
    {
    }

private:
    int _sockfd; // socket创建的是监听套接字，用于服务器listen
    uint16_t _port;
};